﻿# -*-coding: utf-8 -*-
from twisted.internet import reactor, protocol
def PickStr( sData, sStart, sEnd ):
	offset1 = sData.find( sStart );
	if ( offset1 == -1 ):
		return "";
	offset1+=len(sStart )
	offset2 = sData.find( sEnd, offset1 );
	if ( offset2 == -1 ):
		return "";
	return sData[ offset1: offset2]

def Str2Int( s ):
	if ( s == "" ):
		return 0;
	else:
		return int(s)
def StrRep( sSrc, sSub, sStart, sEnd ):
	offset1 = 0
	offset2 = -1
	if ( sStart != ""):
		offset1 = sSrc.find( sStart )
		if ( offset1 == -1 ):
			return
		else:
			offset1 += len(sStart)
	else:
		offset1 = 0
	if ( sEnd!= ""):
		offset2 = sSrc.find( sEnd, offset1 )
		if ( sEnd == -1 ):
			return
	else:
		offset2 = -1;
	return sSrc[:offset1]+sSub+sSrc[offset2:];
	
class PackageBase(object):
	sHead = "";
	sBody = "";
	def Parse(self, data, readall =False ):
		sHead = ""
		sBody = ""
		if ( readall == True ):
			tp = data.split( "\n" )
			data = ""
			for item in tp:
				data += item.strip('\r') + "\r\n"
		lHeadEnd = data.find("\r\n\r\n");
		if (  lHeadEnd == -1 ):
			return 0;
		lHeadEnd += 4
		if ( readall == True ):
			self.sHead = data[0:lHeadEnd];
			self.sBody = data[lHeadEnd:];
			if ( len( self.sBody) > 0 ):
				self.SetField("Content-Type","text/xml;charset=utf-8");
				self.SetField( "Content-Length", str(len(self.sBody)) );
			return len(data)
		else:
			sHead = data[0:lHeadEnd];
			bodylen = Str2Int(PickStr( sHead, "Content-Length:", "\r\n" ).strip());
			if ( bodylen > len(data)-lHeadEnd ):
				return 0;
			self.sHead = sHead;
			self.sBody = data[lHeadEnd:lHeadEnd+bodylen];
			return len(self.sHead) + len(self.sBody)
	def GetString(self):
		return self.sHead+self.sBody
	def SetField( self, sField, sValue ):
		offset1 = self.sHead.find( "\r\n"+sField+":" )
		if ( offset1 != -1 ):
			offset2 = self.sHead.find( "\r\n", offset1+3 )
			self.sHead = self.sHead[:offset1]+"\r\n"+sField+":"+sValue+self.sHead[offset2:];
		else:
			self.sHead = self.sHead.replace( "\r\n\r\n", "\r\n"+sField+":"+sValue+"\r\n\r\n", 2 );
		return self.sHead
	def GetField( self, sField ):
		offset1 = self.sHead.find( "\r\n"+sField+":" );
		if ( offset1 == -1 ):
			return "";
		offset1+=len(sField)+3
		offset2 = self.sHead.find( "\r\n", offset1 );
		if ( offset2 == -1 ):
			return "";
		return self.sHead[ offset1: offset2]
	def IsAnswer(self):
		a = self.sHead.find( "SIP/2.0" )
		b = self.sHead.find( "RTSP/1.0" )
		c = self.sHead.find( "HTTP/1.1" )
		d = self.sHead.find( "HYCP/1.0" )
		return ( a == 0 or b == 0 or c == 0 or d == 0 )

class PackageRequest(PackageBase):
	def Parse( self, data, readall = False ):
		length = super( PackageRequest, self ).Parse( data, readall );
		if ( 0 < length ):
			FirstLine = self.sHead[ 0: self.sHead.find( "\r\n" ) ]
			list = FirstLine.split(None, 2 );
			self.sMethod = list[0]
			self.sPath = list[1]
			self.sProtocol = list[2]
		return length
	def ParseBase( self, base ):
		self.sHead = base.sHead;
		self.sBody = base.sBody;
		FirstLine = self.sHead[ 0: self.sHead.find( "\r\n" ) ]
		list = FirstLine.split(None, 2 );
		self.sMethod = list[0]
		self.sPath = list[1]
		self.sProtocol = list[2]
		
class PackageAnswer(PackageBase):
	def Parse( self, data, readall = False ):
		length = super( PackageAnswer, self ).Parse( data, readall )
		if ( 0 < length ):
			FirstLine = self.sHead[ 0 : self.sHead.find( "\r\n" ) ]
			list = FirstLine.split(None, 2 )
			if ( len(list)>=1):
				self.sProtocol = list[0]
			if ( len(list)>=2):
				self.sCode = list[1]
			if ( len(list)>=3):
				self.sInfo = list[2]
		return length
	def ParseBase( self, base ):
		self.sHead = base.sHead;
		self.sBody = base.sBody;
		FirstLine = self.sHead[ 0: self.sHead.find( "\r\n" ) ]
		list = FirstLine.split(None, 2 )
		if ( len(list)>=1):
			self.sProtocol = list[0]
		if ( len(list)>=2):
			self.sCode = list[1]
		if ( len(list)>=3):
			self.sInfo = list[2]

class Message:
	request = PackageRequest()
	answer = PackageAnswer()
	def __init__(self, request="", answer="" ):
		self.request.Parse( request, True )
		self.answer.Parse( answer, True )
	def ParseAnswer( self, sData ):
		length = self.answer.Parse( sData, True )
		cseq = self.request.GetField( "CSeq" )
		if ( cseq != "" ):
			self.answer.SetField( "CSeq", cseq )
		if ( 0 == sData.find( "SIP/2.0" ) ):
			self.answer.SetField( "From", self.request.GetField( "From" ) )
			self.answer.SetField( "To", self.request.GetField( "To" ) )
			self.answer.SetField( "Call-ID", self.request.GetField( "Call-ID" ) )
		return length;

class UniversaService(protocol.Protocol):
	data = ""
	def FindAnswer(self, path):
		if ( self.factory.dict.has_key(path) ):
			return self.factory.dict[path]
		else:
			return self.factory.dict["error"]
	def connectionMade(self):
		print "@@connect from:",self.transport.getPeer().host
	def dataReceived(self,data):
		print "<<", data
		self.data += data;
		msg = Message();
		length = msg.request.Parse( data )
		while ( length > 0 ):
			self.data = self.data[ length:];
			sAnswer = self.FindAnswer( msg.request.sPath )
			msg.ParseAnswer( sAnswer )
			self.transport.write( msg.answer.GetString() );
			print ">>", msg.answer.GetString()
			length = msg.request.Parse( self.data )
